﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data.SqlServerCe;
using System.Windows.Interop;
using System.Windows.Forms;
using Microsoft.Win32;
using MyTime.Data;
using System.Collections.ObjectModel;
using System.IO;

namespace MyTime
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private const string TempData = @".\TempFolder";

        private const string DataFolder = @".\AttachedData";

        /// <summary>
        /// Connection string.
        /// </summary>
        private string connectionString = @"Data Source=.\Data\MyTimeData.sdf; password='mySecureDat'";

        /// <summary>
        /// Notify Icon.
        /// </summary>
        private System.Windows.Forms.NotifyIcon MyNotifyIcon;

        private TaskLog lastTaskLog;

        /// <summary>
        /// The hotkey capture object.
        /// </summary>
        private HotKey _hotkey;

        /// <summary>
        /// Flag to enable/disable endtime update.
        /// </summary>
        private bool updateEndTime;

        /// <summary>
        /// Last saved task primary key.
        /// </summary>
        private long lastTask;

        private ObservableCollection<string> FileList;

        /// <summary>
        /// Initializes a new instance of the <see cref="MainWindow"/> class.
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();
            FileList = new ObservableCollection<string>();
            if (Directory.Exists(TempData))
                Directory.Delete(TempData, true);

            Directory.CreateDirectory(TempData);
            try
            {
                MyNotifyIcon = new System.Windows.Forms.NotifyIcon();
                MyNotifyIcon.Icon = new System.Drawing.Icon(
                                @"Icons\start.ico");
                MyNotifyIcon.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(MyNotifyIcon_MouseDoubleClick);
                MyNotifyIcon.ContextMenu = new System.Windows.Forms.ContextMenu();
                MyNotifyIcon.ContextMenu.MenuItems.Add("Exit", exitClick);

                this.StateChanged += new EventHandler(Window_StateChanged);

                var test = System.Security.Principal.WindowsIdentity.GetCurrent();
                Microsoft.Win32.SystemEvents.SessionSwitch += new Microsoft.Win32.SessionSwitchEventHandler(SystemEvents_SessionSwitch);

                Loaded += (s, e) =>
                {
                    _hotkey = new HotKey(ModifierKeys.Windows | ModifierKeys.Alt, Keys.Space, this);
                    _hotkey.HotKeyPressed += new Action<HotKey>(hotKeyPressed);
                };
                txtTaskName.Focus();
                txtTaskName.CaptureMouse();

                MyTimeData data = new MyTimeData(connectionString);
                txtTaskName.AutoCompleteList = data.TaskLog.Select(p => p.TaskName).ToList<string>();
                txtCategoryName.AutoCompleteList = data.TaskLog.Select(p => p.TaskCategory).ToList<string>();
                if (data.TaskLog.Count() > 0)
                    lastTaskLog = data.TaskLog.OrderByDescending(x => x.TimeStamp).Take(1).First();
                lstListBox.ItemsSource = FileList;
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.Message);
            }
        }




        /// <summary>
        /// Handles the SessionSwitch event of the SystemEvents control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Microsoft.Win32.SessionSwitchEventArgs"/> instance containing the event data.</param>
        void SystemEvents_SessionSwitch(object sender, Microsoft.Win32.SessionSwitchEventArgs e)
        {
            if (e.Reason == SessionSwitchReason.SessionLock)
            {
                //I left my desk
                UpdateEndTime();
            }
            else if (e.Reason == SessionSwitchReason.SessionUnlock)
            {
                //I returned to my desk
                this.WindowState = System.Windows.WindowState.Normal;
            }
        }

        /// <summary>
        /// Exits the click.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        void exitClick(object sender, EventArgs e)
        {
            UpdateEndTime();
            this.Close();
        }

        /// <summary>
        /// Handles the MouseDoubleClick event of the MyNotifyIcon control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Forms.MouseEventArgs"/> instance containing the event data.</param>
        void MyNotifyIcon_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            TimeViewer tm = new TimeViewer();
            tm.ShowDialog();
        }

        /// <summary>
        /// Handles the StateChanged event of the Window control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void Window_StateChanged(object sender, EventArgs e)
        {
            if (this.WindowState == WindowState.Minimized)
            {
                this.ShowInTaskbar = false;
                //MyNotifyIcon.BalloonTipTitle = "Minimize Sucessful";
                //MyNotifyIcon.BalloonTipText = "Minimized the app ";
                //MyNotifyIcon.ShowBalloonTip(400);
                MyNotifyIcon.Visible = true;
            }
            else if (this.WindowState == WindowState.Normal)
            {
                MyNotifyIcon.Visible = false;
                this.ShowInTaskbar = true;
            }
        }

        private void hotKeyPressed(HotKey key)
        {
            this.WindowState = WindowState.Normal;
            this.Visibility = System.Windows.Visibility.Visible;

            if (lastTaskLog != null)
            {
                //txtTaskName.Text = lastTaskLog.TaskName;
                //txtCategoryName.Text = lastTaskLog.TaskCategory;
            }
            MyTimeData data = new MyTimeData(connectionString);
            txtTaskName.AutoCompleteList = data.TaskLog.Select(p => p.TaskName).Distinct().ToList<string>();
            txtCategoryName.AutoCompleteList = data.TaskLog.Select(p => p.TaskCategory).Distinct().ToList<string>();
            //Clear Temp files
            FileList.Clear();
            if (Directory.Exists(TempData))
                Directory.Delete(TempData, true);

            Directory.CreateDirectory(TempData);
        }

        /// <summary>
        /// Handles the DefaultAction event of the txtTaskName control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void txtTaskName_DefaultAction(object sender, EventArgs e)
        {
            UpdateEndTime();
            Save();
            //txtTaskName.Text = string.Empty;
            //txtCategoryName.Text = string.Empty;
        }

        /// <summary>
        /// Handles the EscapeAction event of the txtTaskName control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void txtTaskName_EscapeAction(object sender, EventArgs e)
        {
            this.WindowState = WindowState.Minimized;
            this.ShowInTaskbar = false;
            MyNotifyIcon.Visible = true;
            //txtTaskName.Text = string.Empty;
            //txtCategoryName.Text = string.Empty;
        }

        #region dbTasks

        /// <summary>
        /// Saves the task to DB.
        /// </summary>
        private void Save()
        {
            if (!string.IsNullOrEmpty(txtTaskName.Text))
            {
                MyTimeData data = new MyTimeData(connectionString);
                TaskLog newTask = new TaskLog();
                lastTask = DateTime.UtcNow.ToFileTime();
                newTask.TimeStamp = lastTask.ToString();
                newTask.TaskName = txtTaskName.Text;
                newTask.TaskCategory = txtCategoryName.Text;
                newTask.TaskDescription = txtDescription.Text;
                if(Directory.Exists(TempData) && Directory.GetFiles(TempData,"*",SearchOption.AllDirectories).Count()>0 )
                    TaskLogAttachedFileHandler.CopyDirectory(TempData, DataFolder + "\\" + lastTask.ToString());
                if (Directory.Exists(DataFolder + "\\" + lastTask.ToString()))
                {
                    DirectoryInfo dr = new DirectoryInfo(DataFolder + "\\" + lastTask.ToString());
                    newTask.AttachedData = dr.FullName;                    
                }
                newTask.StartTime = DateTime.Now;
                lastTaskLog = newTask;
                data.TaskLog.InsertOnSubmit(newTask);
                data.SubmitChanges();
                updateEndTime = true;

                
            }
            this.WindowState = WindowState.Minimized;
        }

        /// <summary>
        /// Updates the task end time in DB.
        /// </summary>
        /// <param name="endTime">The end time.</param>
        private void UpdateEndTime()
        {
            if (!updateEndTime)
                return;

            MyTimeData data = new MyTimeData(connectionString);
            var TaskLoglist = (from p in data.TaskLog.AsEnumerable<TaskLog>()
                               where p.TimeStamp == lastTask.ToString()
                               select p).FirstOrDefault();

            if (TaskLoglist != null)
            {
                TaskLoglist.EndTime = DateTime.Now;
            }
            data.SubmitChanges();

            updateEndTime = false;
            this.WindowState = WindowState.Minimized;
        }

        #endregion

        private void ListBox_DragOver(object sender, System.Windows.DragEventArgs e)
        {
            bool dropEnabled = true;

            if (e.Data.GetDataPresent(System.Windows.DataFormats.FileDrop, true))
            {
                string[] filenames = e.Data.GetData(System.Windows.DataFormats.FileDrop, true) as string[];

                foreach (string filename in filenames)
                {
                    if (System.IO.Path.GetExtension(filename).ToUpperInvariant() != ".CS")
                    {
                        dropEnabled = false;
                        break;
                    }
                }
            }
            else
            {
                dropEnabled = false;
            }

            if (!dropEnabled)
            {
                e.Effects = System.Windows.DragDropEffects.None;
                e.Handled = true;
            }
        }

        private void ListBox_Drop(object sender, System.Windows.DragEventArgs e)
        {
            string[] droppedFilenames = e.Data.GetData(System.Windows.DataFormats.FileDrop, true) as string[];
            ObservableCollection<string> files =new ObservableCollection<string>();
            if (droppedFilenames != null)
            {
                foreach (var item in droppedFilenames)
                {
                    if (File.Exists(item))
                    {
                        files.Add(item);
                        FileList.Add(item);
                    }
                    else if (Directory.Exists(item))
                    {
                        files.Add(item);
                        FileList.Add(item);
                    }
                }
                TaskLogAttachedFileHandler.SaveFiles(files,TempData);
                
            }
            else if (e.Data.GetDataPresent("FileGroupDescriptor"))
            {
                try
                {
                    //wrap standard IDataObject in OutlookDataObject
                    OutlookDataObject dataObject = new OutlookDataObject(e.Data);

                    //get the names and data streams of the files dropped
                    string[] filenames = (string[])dataObject.GetData("FileGroupDescriptorW");
                    MemoryStream[] filestreams = (MemoryStream[])dataObject.GetData("FileContents");

                    for (int fileIndex = 0; fileIndex < filenames.Length; fileIndex++)
                    {
                        //use the fileindex to get the name and data stream
                        string filename = filenames[fileIndex];
                        MemoryStream filestream = filestreams[fileIndex];                        

                        //save the file stream using its name to the application path
                        FileStream outputStream = File.Create(TempData+"\\"+ filename);
                        filestream.WriteTo(outputStream);
                        outputStream.Close();
                        FileList.Add(filename);
                    }
                }
                catch (Exception ex)
                {
                    
                }
                
            }
            
        }
    }
}
